package ca.cbc.medialib.dao;

import java.util.Date;
import java.util.List;

import org.hibernate.criterion.Restrictions;

import ca.cbc.medialib.entity.Category;
import ca.cbc.medialib.entity.Media;

public class MediaDAO extends EntityDAO<Media> {
	private CategoryDAO categoryDAO;
	
	public CategoryDAO getCategoryDAO() {
		return categoryDAO;
	}

	public void setCategoryDAO(CategoryDAO categoryDAO) {
		this.categoryDAO = categoryDAO;
	}

	@Override
	public void delete(Media m)  {
		Media media = super.findById(m.getReleaseId());
        /**
         * Delete category only if there is no media associated with it
         */
         List<Category> cats = media.getCategories();
         if (cats != null) {
        	 for (Category c : cats) {
        		 deleteCategoryIfEmpty(c, media);
        	 }
         }
         super.delete(media);
	}

	private void deleteCategoryIfEmpty(Category cat, Media m){
        if (cat.getChildren().size()==0 && cat.getMedias().size() == 1 && cat.getMedias().get(0).getReleaseId()==m.getReleaseId()){
        	categoryDAO.delete(cat, m);
        }
    }
	
	@Override
	public String getFullClassName() {
		return Media.class.getCanonicalName();
	}
	
    @SuppressWarnings("unchecked")
	public List<Media> listExpiredMobileMedia(int first, int max) {
        List<Media> mediaList = getCurrentSession().createCriteria(Media.class)
                .add(Restrictions.le("mobileExpiryDate", new Date()))
                .add(Restrictions.le("availableInMobile", "true"))
                .add(Restrictions.ne("mobileId", 0L))
                .setFirstResult(first)
                .setMaxResults(max)
                .list();
        return mediaList;
    }
    
    @Override
    public Media merge(Media media) {
    	//don't save category if not mobile
    	if(media.getMobileId() == 0) {
            media.removeAllCategories();
        }
    	
    	Media oldMedia = super.findById(media.getReleaseId());

        for(Category oldCat : oldMedia.getCategories()){
            if(!media.getCategories().contains(oldCat)){
            	deleteCategoryIfEmpty(oldCat, oldMedia);
            }
        }

        List<Category> categories = media.getCategories();
        if (categories != null) {
            for (Category c : categories) {
            	//logger.debug("Category id = {}, categoryDAO.findById(c.getId()) = {}", c.getId(), categoryDAO.findById(c.getId()) == null);
            	if(categoryDAO.findById(c.getId()) == null) {
            		categoryDAO.save(c);
            	} else {
            		categoryDAO.merge(c);
            	}
            }
        }
        
        Media m = super.merge(media);
        return m;
    }
    
    @Override
    public void save(Media media) {
    	//don't save category if not mobile
    	if(media.getMobileId() == 0) {
            media.removeAllCategories();
        }

        //save category if exist
        List<Category> categories = media.getCategories();
        if (categories != null) {
        	for (Category c : categories) {
            	if(categoryDAO.findById(c.getId()) == null) {
            		categoryDAO.save(c);
            	} else {
            		categoryDAO.merge(c);
            	}
            }
        }
        
        //save media ifself
        super.save(media);
    }
}
